package com.server.thisService.common;

import com.project.annotation.model.base.RequestBase;
import com.project.thisCommon.common.ConvertEntity;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.apache.commons.lang.StringUtils;
import org.apache.http.client.utils.DateUtils;

import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.ParseException;
import java.util.*;

public class BaseCommon {

    public static <T> RequestBase<T> ConvertToRequest(RequestBase req) {
        RequestBase<T> res = new RequestBase<>();
        res.setToken(req.getToken());
        res.setUserId(req.getUserId());
        res.setAppId(req.getAppId());
        res.setFunc(req.getFunc());
        res.setUserCode(req.getUserCode());
        res.setUserName(req.getUserName());

        return res;
    }

    public static <T> RequestBase<T> ConvertToNullRequest(RequestBase req, Class<T> cls) {
        RequestBase<T> res = new RequestBase<>();
        res.setToken(req.getToken());
        res.setUserId(req.getUserId());
        res.setAppId(req.getAppId());
        res.setFunc(req.getFunc());
        res.setUserCode(req.getUserCode());
        res.setUserName(req.getUserName());

        try {
            res.setBody(cls.newInstance());
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        return res;
    }

    public static <T> RequestBase<T> ConvertToRequest(RequestBase req, Class<T> cls) {
        RequestBase<T> res = new RequestBase<>();
        res.setToken(req.getToken());
        res.setUserId(req.getUserId());
        res.setAppId(req.getAppId());
        res.setFunc(req.getFunc());
        res.setUserCode(req.getUserCode());
        res.setUserName(req.getUserName());

        try {
            if (null == req.getBody()) {
                res.setBody(cls.newInstance());
            } else {
                res.setBody(ConvertEntity.copyEntity(req.getBody(), cls));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return res;
    }

    public static boolean CheckList(List list) {
        return null != list && list instanceof List && list.size() > 0;
    }

    public static Object ReadMapValue(String path, Map map) {
        String[] sp = path.split(".");
        Object m = map;
        for (String s : sp) {
            if (m instanceof Map) {
                Map item = (Map) m;
                if (item.containsKey(s)) {
                    m = item.get(s);
                }
            } else {
                break;
            }
        }

        return m;
    }

    public static String ImageToBase64(File fs) throws IOException {
        try(InputStream ip = new FileInputStream(fs)) {
            return ImageToBase64(ip);
        }
    }

    public static String ImageToBase64(InputStream ips) throws IOException {
        byte[] b = new byte[ips.available()];
        ips.read(b);
        return Base64.getEncoder().encodeToString(b);
    }

    public static void SaveBase64(String base64, File f) throws IOException {
        byte[] bs = Base64.getDecoder().decode(base64);
        try (OutputStream fo = new FileOutputStream(f)) {
            fo.write(bs);
            fo.flush();
        }
    }

    public static String ChinaWeek(Date dt) {
        String[] weeks = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        int week_index = cal.get(Calendar.DAY_OF_WEEK);

        return weeks[week_index > 0 ? week_index - 1 : week_index];
    }

    public static Map<String, String> UrlDecode(String url) throws UnsupportedEncodingException {
        Map<String, String> res = new TreeMap<>();
        String[] ps = url.split("&");
        for (String s : ps) {
            String[] pm = s.split("=");
            if (pm.length == 2) {
                res.put(pm[0], URLDecoder.decode(pm[1], "utf-8"));
            }
        }

        return res;
    }

    public static String UrlEncoder(Map<String, String> item) throws UnsupportedEncodingException {
        List<String> sb = new ArrayList<>();
        item.forEach((k, v)->{
            try {
                String en = URLEncoder.encode(v, "utf-8");
                sb.add(String.format("%s=%s", k, en));
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        });

        return String.join("&", sb);
    }

    public static Date GetDate(Date dt) throws ParseException {
        String d = DateUtils.formatDate(dt, "yyyy-MM-dd");
        return DateUtils.parseDate(d, new String[] {"yyyy-MM-dd"});
//        String d = CommonFunction.GetLocalDateString(dt, "yyyy-MM-dd");
//        return CommonFunction.GetLocalDate(d, "yyyy-MM-dd");
    }

    public static void RunCmd(List<String> commands) throws IOException {
        ProcessBuilder builder = new ProcessBuilder();
        builder.command(commands);
        Process p = builder.start();
        try {
            p.waitFor();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        try(BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()))) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        }
    }

    public static void Zip(File f, File out) throws IOException {
        if (f.exists()) {
            List<String> commands = new ArrayList<>();
            commands.add("zip");
            commands.add("-r");
            commands.add(out.getCanonicalPath());
            commands.add(f.getCanonicalPath());
            RunCmd(commands);
        }
    }

    public static void Deletes(File f) throws IOException {
        if (f.exists()) {
            List<String> commands = new ArrayList<>();
            commands.add("rm");
            commands.add("-rf");
            commands.add(f.getCanonicalPath());

            RunCmd(commands);
        }
    }

    public static String Pinyin(String val) throws BadHanyuPinyinOutputFormatCombination {
        HanyuPinyinOutputFormat py_format = new HanyuPinyinOutputFormat();
        py_format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        return PinyinHelper.toHanYuPinyinString(val, py_format, StringUtils.EMPTY, false);
    }

    public static Integer Age(Date birthday) {
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH);
        int day = cal.get(Calendar.DAY_OF_MONTH);

        cal.setTime(birthday);

        int birthday_year = cal.get(Calendar.YEAR);
        int birthday_month = cal.get(Calendar.MONTH);
        int birthday_day = cal.get(Calendar.DAY_OF_MONTH);

        int age = year - birthday_year;

        if (month < birthday_month) {
            age--;
        } else if (month == birthday_month && day < birthday_day) {
            age--;
        }

        return age;
    }
}
